package com.qingzhuge.sms.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Maps;
import com.qingzhuge.cache.autoconfigure.J2CacheProperties;
import com.qingzhuge.common.Assert;
import com.qingzhuge.common.HttpCode;
import com.qingzhuge.dto.response.BaseResponseDto;
import com.qingzhuge.exception.ValidatorException;
import com.qingzhuge.service.BasePkLongServiceImpl;
import com.qingzhuge.sms.SmsUtil;
import com.qingzhuge.sms.dao.ISysSmsDao;
import com.qingzhuge.sms.entity.SysSms;
import com.qingzhuge.sms.service.IAccountValidateHandler;
import com.qingzhuge.sms.service.ISysSmsService;
import com.qingzhuge.sms.vo.SmsRequest;
import com.qingzhuge.sms.vo.SmsSendDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;

import static com.qingzhuge.sms.service.impl.SysSmsServiceImpl.CACHE_NAME;

/**
 * @author : zero.xiao
 * @description :
 * @date : 2018/9/21 0021 上午 10:41
 * @modified :
 * @since :
 */
@Service
@CacheConfig(cacheNames = CACHE_NAME)
public class SysSmsServiceImpl extends BasePkLongServiceImpl<ISysSmsDao, SysSms> implements ISysSmsService {
    static final String CACHE_NAME = "sysSmsServiceImpl";
    @Autowired(required = false)
    private J2CacheProperties properties;
    @Autowired(required = false)
    private IAccountValidateHandler accountValidateHandler;

    @Override
    public SmsSendDetails send(String phone, String value, String templateCode) {
        SysSms sysSms = this.findByEnableIsTrue();
        if(null != sysSms) {
            SmsRequest request = new SmsRequest();
            request.setAccessKeyId(sysSms.getAccessKeyId());
            request.setAccessKeySecret(sysSms.getAccessKeySecret());
            request.setSign(sysSms.getSignName());
            request.setPhone(phone);
            request.setValue(value);
            request.setTemplateCode(templateCode);
            //发短信
            try {
                return SmsUtil.sendSms(request);
            } catch (ClientException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public SmsSendDetails querySendDetails(String phone, String bizId, Long pageSize, Long currentPage) {
        SysSms sysSms = baseDao.findByEnableIsTrue();
        if(null != sysSms) {
            SmsRequest request = new SmsRequest();
            request.setAccessKeyId(sysSms.getAccessKeyId());
            request.setAccessKeySecret(sysSms.getAccessKeySecret());
            request.setBizId(bizId);
            request.setPageSize(pageSize);
            request.setCurrentPage(currentPage);
            request.setPhone(phone);
            try {
                return SmsUtil.querySendDetails(request);
            } catch (ClientException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Cacheable
    @Override
    public SysSms findByEnableIsTrue() {
        return baseDao.findByEnableIsTrue();
    }

    @Override
    public void saveSmsCode2Cache(String key, String code) {
        long expiration = 60;
        if (null != properties){
            expiration = properties.getCodeValiExpiration();
        }
        log.debug("保存缓存 saveSmsCode2Cache key:{},code:{},exp:{}", key, code, expiration);
        super.saveCache("smsCode",key, code, expiration);
    }

    @Override
    public String getSmsCodeForCache(String key) {
        String cache = super.getCache("smsCode",key);
        log.debug("获取缓存 getSmsCodeForCache key:{},value:{}", key, cache);
        return cache;
    }

    @Override
    public void deleteSmsCodeForCache(String key) {
        log.debug("删除缓存 deleteSmsCodeForCache key:{}", key);
        super.deleteCache("smsCode",key);
    }

    @Override
    public boolean sendSmsCode(String mobile, String templateCode, String key, int count) {
        String random = randomNumber(count);
        Map<String,String> map = Maps.newHashMap();
        map.put("code", random);
        boolean smsCode = sendSms(mobile, templateCode, map);
        if (smsCode) {
            this.saveSmsCode2Cache(key, random);
            log.debug("缓存 mobile :{}, 验证码:{}.", mobile, random);
            return true;
        }
        return false;
    }

    @Override
    public boolean sendSms(String mobile, String templateCode, Object value) {
        String json = JSONObject.toJSONString(value);
        SmsSendDetails details = this.send(mobile, json, templateCode);
        details.setSmsCode(json);
        String ok = "OK";
        return Objects.equals(ok, details.getCode());
    }

    @Override
    public BaseResponseDto registerCode(String mobile) {
        BaseResponseDto response = new BaseResponseDto();
        if (Assert.validationMobile(mobile, response)) {
            return response;
        }
        //没有实现手机号验证器验证账号已经注册，验证结果默认为true，表示已验证
        boolean validate = true;
        //如果实现了手机号验证器
        if (null != accountValidateHandler) {
            //验证结果,没有注册
            validate = !accountValidateHandler.validate(mobile);
        }
        if (validate) {
            SysSms sms = this.findByEnableIsTrue();
            if (null != sms && null != sms.getRegisterTemplateCode()) {
                this.sendSmsCode(mobile, sms.getRegisterTemplateCode(), getRegisterCodeKey(mobile), 6);
                response.setResCode(200);
                response.setResMessage("发送成功");
            }
        }else{
            throw  new ValidatorException(HttpCode.ACCOUNT_EXISTS.message(), HttpCode.ACCOUNT_EXISTS.value());
        }
        return response;
    }

    @Override
    public BaseResponseDto loginCode(String mobile) {
        BaseResponseDto response = new BaseResponseDto();
        if (Assert.validationMobile(mobile, response)) {
            return response;
        }
        if (isValidate(mobile)) {
            SysSms sms = this.findByEnableIsTrue();
            if (null != sms && null != sms.getLoginTemplateCode()) {
                this.sendSmsCode(mobile, sms.getLoginTemplateCode(), getLoginCodeKey(mobile), 6);
                response.setResCode(200);
                response.setResMessage("发送成功");
            }
        }else{
            throw  new ValidatorException(HttpCode.NOT_ACCOUNT.message(), HttpCode.NOT_ACCOUNT.value());
        }
        return response;
    }

    @Override
    public BaseResponseDto resetPwdCode(String mobile) {
        BaseResponseDto response = new BaseResponseDto();
        if (Assert.validationMobile(mobile, response)) {
            return response;
        }
        if (isValidate(mobile)) {
            SysSms sms = this.findByEnableIsTrue();
            if (null != sms && null != sms.getResetPwdTemplateCode()) {
                this.sendSmsCode(mobile, sms.getResetPwdTemplateCode(), getResetPwdCodeKey(mobile), 6);
                response.setResCode(200);
                response.setResMessage("发送成功");
            }
        }else{
            throw  new ValidatorException(HttpCode.NOT_ACCOUNT.message(), HttpCode.NOT_ACCOUNT.value());
        }
        return response;
    }

    private boolean isValidate(String mobile){
        //没有实现手机号验证器验证账号已经注册，验证结果默认为true，表示已验证
        boolean validate = true;
        //如果实现了手机号验证器
        if (null != accountValidateHandler) {
            //验证结果,没有注册
            validate = accountValidateHandler.validate(mobile);
        }
        return validate;
    }

    @Override
    public String getRegisterCodeKey(String mobile) {
        return ISysSmsService.CACHE_KEY_SMS_CODE_REGISTER + mobile;
    }

    @Override
    public String getLoginCodeKey(String mobile) {
        return ISysSmsService.CACHE_KEY_SMS_CODE_LOGIN + mobile;
    }

    @Override
    public String getResetPwdCodeKey(String mobile) {
        return ISysSmsService.CACHE_KEY_SMS_CODE_RESET_PASSWORD + mobile;
    }
}
